import bcrypt from 'bcryptjs';
import { logger } from './logger';

/**
 * 密码强度检查结果接口
 */
interface PasswordStrengthResult {
  isValid: boolean;
  score: number; // 0-100
  requirements: {
    length: boolean;
    lowercase: boolean;
    uppercase: boolean;
    number: boolean;
    special: boolean;
  };
  feedback: string[];
}

/**
 * 检查密码强度
 */
export const checkPasswordStrength = (password: string): PasswordStrengthResult => {
  const requirements = {
    length: password.length >= 6,
    lowercase: /[a-z]/.test(password),
    uppercase: /[A-Z]/.test(password),
    number: /\d/.test(password),
    special: /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)
  };

  const feedback: string[] = [];
  let score = 0;

  // 基础长度检查
  if (requirements.length) {
    score += 20;
  } else {
    feedback.push('密码长度至少6个字符');
  }

  // 字符类型检查
  if (requirements.lowercase) score += 15;
  else feedback.push('至少包含一个小写字母');

  if (requirements.uppercase) score += 15;

  if (requirements.number) score += 15;
  else feedback.push('至少包含一个数字');

  if (requirements.special) score += 10;
  else feedback.push('建议包含特殊字符');

  // 长度奖励
  if (password.length >= 8) score += 10;
  if (password.length >= 12) score += 10;
  if (password.length >= 16) score += 5;

  // 常见密码检查
  const commonPasswords = [
    'password', '123456', '123456789', 'qwerty', 'abc123',
    'password123', 'admin', 'root', '111111', '000000'
  ];
  
  if (commonPasswords.includes(password.toLowerCase())) {
    score = Math.max(0, score - 30);
    feedback.push('避免使用常见密码');
  }

  const isValid = requirements.length && requirements.lowercase && 
                 requirements.number;

  return {
    isValid,
    score: Math.min(100, score),
    requirements,
    feedback
  };
};

/**
 * 安全哈希密码
 */
export const hashPassword = async (password: string): Promise<string> => {
  try {
    const saltRounds = 12; // 增加到12轮提高安全性
    const salt = await bcrypt.genSalt(saltRounds);
    return await bcrypt.hash(password, salt);
  } catch (error) {
    logger.error('密码哈希失败', { error });
    throw new Error('密码加密失败');
  }
};

/**
 * 验证密码
 */
export const verifyPassword = async (
  plainPassword: string, 
  hashedPassword: string
): Promise<boolean> => {
  try {
    return await bcrypt.compare(plainPassword, hashedPassword);
  } catch (error) {
    logger.error('密码验证失败', { error });
    return false;
  }
};

/**
 * 生成安全的随机密码
 */
export const generateSecurePassword = (length: number = 12): string => {
  const lowercase = 'abcdefghijklmnopqrstuvwxyz';
  const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  const numbers = '0123456789';
  const special = '!@#$%^&*()_+-=[]{}|;:,.<>?';
  
  const allChars = lowercase + uppercase + numbers + special;
  
  let password = '';
  
  // 确保至少包含每种类型的字符
  password += lowercase[Math.floor(Math.random() * lowercase.length)];
  password += uppercase[Math.floor(Math.random() * uppercase.length)];
  password += numbers[Math.floor(Math.random() * numbers.length)];
  password += special[Math.floor(Math.random() * special.length)];
  
  // 填充剩余长度
  for (let i = password.length; i < length; i++) {
    password += allChars[Math.floor(Math.random() * allChars.length)];
  }
  
  // 打乱字符顺序
  return password.split('').sort(() => Math.random() - 0.5).join('');
};

/**
 * 密码历史检查（防止重复使用最近的密码）
 */
export const isPasswordReused = async (
  userId: string,
  newPassword: string,
  previousPasswords: string[]
): Promise<boolean> => {
  try {
    for (const oldPassword of previousPasswords) {
      if (await bcrypt.compare(newPassword, oldPassword)) {
        return true;
      }
    }
    return false;
  } catch (error) {
    logger.error('密码重用检查失败', { userId, error });
    return false;
  }
};